package net.chasing.retrofit.util.encode;

import android.text.TextUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by chasing on 2019/6/22.
 * 加密解密类
 */
public class AESUtils {
    // key必须为16位
    public static final String AES_KEY = "it9rfWj#eAht%O$E";
    // 密钥偏移量为16位
    /**
     * 加解密算法/工作模式/填充方式
     * CBC(Cipher Block Chaining, 加密快链)模式，PKCS7Padding补码方式
     * AES是加密方式 CBC是工作模式 PKCS7Padding是填充模式
     */
    private static final String CBC_PKCS7_PADDING = "AES/CBC/PKCS7Padding";
    private static final String AES = "AES";

    /**
     * AES 加密
     *
     * @param strClearText 待加密内容
     * @return 返回Base64转码后的加密数据
     */
    public static String encryptAES(String strClearText) {
        if (TextUtils.isEmpty(strClearText)) return null;
        String ivPara = CodeUtils.getRandomString(16);
        byte[] ivBytes = ivPara.getBytes();
        try {
            byte[] raw = AES_KEY.getBytes();
            // 创建AES密钥
            SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
            // 创建密码器
            Cipher cipher = Cipher.getInstance(CBC_PKCS7_PADDING);
            // 创建偏移量
            IvParameterSpec iv = new IvParameterSpec(ivBytes);
            // 初始化加密器
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            // 执行加密操作
            byte[] cipherText = cipher.doFinal(strClearText.getBytes());
            int offset = (cipherText[0] & 0XFF) % 15 + 1;
            byte[] encryptBytes = new byte[cipherText.length + ivBytes.length];
            System.arraycopy(cipherText, 0, encryptBytes, 0, offset);
            System.arraycopy(ivBytes, 0, encryptBytes, offset, ivBytes.length);
            System.arraycopy(cipherText, offset, encryptBytes, offset + ivBytes.length, cipherText.length - offset);
            return CodeUtils.byte2hex(encryptBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * AES 解密
     *
     * @param strCipherText 待解密内容
     * @return 返回Base64转码后的加密数据
     */
    public static String decryptAES(String strCipherText) {
        if (TextUtils.isEmpty(strCipherText)) return null;
        byte[] cipherTxtByte = CodeUtils.hexStr2HexByte(strCipherText);
        int offset = (cipherTxtByte[0] & 0xff) % 15 + 1;
        byte[] ivByte = new byte[16];
        byte[] txtByte = new byte[cipherTxtByte.length - 16];
        System.arraycopy(cipherTxtByte, 0, txtByte, 0, offset);
        System.arraycopy(cipherTxtByte, offset, ivByte, 0, 16);
        System.arraycopy(cipherTxtByte, offset + 16, txtByte, offset, txtByte.length - offset);
        try {
            byte[] raw = AES_KEY.getBytes();
            // 创建AES秘钥
            SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
            // 创建密码器
            Cipher cipher = Cipher.getInstance(CBC_PKCS7_PADDING);
            // 创建偏移量
            IvParameterSpec iv = new IvParameterSpec(ivByte);
            // 初始化解密器
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            // 执行解密操作
            byte[] clearText = cipher.doFinal(txtByte);
            return new String(clearText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

//    /**
//     * AES 加密
//     *
//     * @param strClearText 待加密内容
//     * @return 返回Base64转码后的加密数据
//     */
//    public static String encryptAES(String strClearText, String key) {
//        if (TextUtils.isEmpty(strClearText)) return null;
//        return encryptAES(strClearText, key.getBytes());
//    }
//
//    /**
//     * AES 加密
//     *
//     * @param strClearText 待加密内容
//     * @return 返回Base64转码后的加密数据
//     */
//    public static String encryptAES(String strClearText, byte[] key) {
//        if (TextUtils.isEmpty(strClearText)) return null;
//        try {
//            // 创建AES密钥
//            SecretKeySpec skeySpec = new SecretKeySpec(key, AES);
//            // 创建密码器
//            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance(AES);
//            // 初始化加密器
//            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
//            // 执行加密操作
//            byte[] cipherText = cipher.doFinal(strClearText.getBytes());
//            String strBase64Content = Base64.encodeToString(cipherText, Base64.URL_SAFE); // encode it by BASE64 again
//            strBase64Content = strBase64Content.replaceAll(Objects.requireNonNull(System.getProperty("line.separator")), "");
//            return strBase64Content;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//
//    /**
//     * AES 解密
//     *
//     * @param strCipherText 待解密内容
//     * @return 返回Base64转码后的加密数据
//     */
//    public static String decryptAES(String strCipherText, String key) {
//        if (TextUtils.isEmpty(strCipherText)) return null;
//        return decryptAES(strCipherText, key.getBytes());
//    }
//
//    /**
//     * AES 解密
//     *
//     * @param strCipherText 待解密内容
//     * @return 返回Base64转码后的加密数据
//     */
//    public static String decryptAES(String strCipherText, byte[] key) {
//        if (TextUtils.isEmpty(strCipherText)) return null;
//        try {
//            // 创建AES秘钥
//            SecretKeySpec skeySpec = new SecretKeySpec(key, AES);
//            // 创建密码器
//            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance(AES);
//            // 初始化解密器
//            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
//            // 执行解密操作
//            byte[] cipherText = Base64.decode(strCipherText, Base64.URL_SAFE); // decode by BASE64 first
//            byte[] clearText = cipher.doFinal(cipherText);
//            return new String(clearText);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
}
